#ifndef _THREAD_POOL_HPP_
#define _THREAD_POOL_HPP_

#include <queue>
#include <vector>
#include "Thread.hpp"
#include "Cond.hpp"

// using namespace Thread;

namespace Thread_Pool
{
    const int defaultnum = 5;

    template < class T >
    class ThreadPool
    {
    public:
        ThreadPool(int num = defaultnum)
            :_n(num)
        {
            // 执行线程。
            for(int i = 0;i < num;++i)
            {
                // 缺乏this指针就调用不了。
                _threads.emplace_back(Thread::Thread([this](){HandlerTask();}));
            }
        }
        ~ThreadPool()
        {
            int n = _threads.size();
            for(int i = 0;i < n;++i)
            {
                _threads.pop_back();
            }

            n = _taskq.size();
            for(int i = 0;i < n;++i)
            {
                _taskq.pop();
            }
        }

        void Start()
        {
            for(auto& e : _threads)
            {
                e.Start();
            }
        }

        void Insert(T task)
        {
            _taskq.push(task);
        }
        
        // 执行线程池中对应的函数。
        void HandlerTask()
        {
            char name[50];
            
            // 获取当前线程的名字。
            pthread_getname_np(pthread_self(),name,sizeof(name));

            while(true)
            {
                T _t;

                // 访问临界资源
                {
                    Lock_Manager manager(_mutex);

                    while(_taskq.empty())
                    {
                        _cond.Wait(_mutex);
                    }

                    _t = _taskq.front();
                    _taskq.pop();
                }

                // 都取出来了就没必要加锁了。
                _t();
            }
        }
    private:
        std::vector<Thread::Thread> _threads;
        std::queue<T> _taskq;
        Condition::Cond _cond;
        Mutex _mutex;
        int _n;
    };
}

#endif